#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "lockercompartmentLoad.h"
#include "lockerLoad.h"
typedef int bool;
#define true 1
#define false 0

int loadLockerCompartments(char const *filename){
	FILE *ptr_file;
	ptr_file=fopen(filename,"r");
	if(!ptr_file){
		return 1;
	}
	int maxlinelen;
	int numlines=getFileInfo(ptr_file,&maxlinelen);
	lockercompartmentcount=numlines;
	lockercompartmentdata=(struct LockerCompartmentVars*) calloc(numlines,sizeof(struct LockerCompartmentVars));
	char *buf=(char*) malloc(maxlinelen*sizeof(char));
	for(int i=0;i<numlines;i++){
		fgets(buf,maxlinelen,ptr_file);//load line into buffer;
		strcpy(lockercompartmentdata[i].lockerid,strtok(buf,"/"));
		char *ph = strtok(NULL,"/");
		lockercompartmentdata[i].compartmentid=atoi(ph);
		ph = strtok(NULL,"/");
		lockercompartmentdata[i].lockercode=atoi(ph);
		strcpy(lockercompartmentdata[i].state,strtok(NULL,"/"));
		ph = strtok(NULL,"/");
		lockercompartmentdata[i].placementdate=atoi(ph);
		ph = strtok(NULL,"/");
		lockercompartmentdata[i].expirydate=atoi(ph);
	}
	fclose(ptr_file);
	return 0;
}

int writeLockerCompartments(char const *filename){
    FILE *ptr_file;
	ptr_file=fopen(filename,"w");
	if(!ptr_file){
		return 1;
	}
	for(int i=0;i<lockercompartmentcount;i++){
		fprintf(ptr_file,"%s/%d/%d/%s/%d/%d\n",lockercompartmentdata[i].lockerid,lockercompartmentdata[i].compartmentid,lockercompartmentdata[i].lockercode,lockercompartmentdata[i].state,lockercompartmentdata[i].placementdate,lockercompartmentdata[i].expirydate);
	}
	fclose(ptr_file);
	free(lockercompartmentdata);
	return 0;
}

void addLockerCompartment(struct LockerCompartmentVars n){
	lockercompartmentdata=(struct LockerCompartmentVars*) realloc(lockercompartmentdata,++lockercompartmentcount*sizeof(struct LockerCompartmentVars));
	lockercompartmentdata[lockercompartmentcount-1]=n;
}

void rmLockerCompartment(int index){
	for(int i=index;i<lockercompartmentcount-1;i++){
		lockercompartmentdata[i]=lockercompartmentdata[i+1];
	}
	lockercompartmentdata=(struct LockerCompartmentVars*) realloc(lockercompartmentdata,--lockercompartmentcount*sizeof(struct LockerCompartmentVars));
}



void readLockerCompartments()
{
    for (int i = 0; i < lockercompartmentcount; i++)
    {
        printf("%s/%d/%d/%s/%d/%d\n",lockercompartmentdata[i].lockerid,lockercompartmentdata[i].compartmentid,lockercompartmentdata[i].lockercode,lockercompartmentdata[i].state,lockercompartmentdata[i].placementdate,lockercompartmentdata[i].expirydate);
    }
}

void changeCompartmentState(int index){
	int aux;
	if (strcmp(lockercompartmentdata[index].state, "ocupado")==0){
		strcpy(lockercompartmentdata[index].state, "vacío");
		for(int i=0;i<lockercount;i++){
			if(strcmp(lockercompartmentdata[index].lockerid,lockerdata[i].lockerid)==0)
				aux=i;
		}
		removeUsed(aux);
	}

	else{
		strcpy(lockercompartmentdata[index].state, "ocupado");
		for(int i=0;i<lockercount;i++){
			if(strcmp(lockercompartmentdata[index].lockerid,lockerdata[i].lockerid)==0)
				aux=i;
		}
		addUsed(aux);
	}
}

void changeLockerCode(int index){
	srand(time(NULL));
	lockercompartmentdata[index].lockercode=rand() % 111112 + 999999; //random number of 6 digits 
}

void pickupCompartmentLocker(){
	bool bool=false;
	int code, date;
	printf("\nInserte la fecha de hoy sin formato:\n(ej:01012020): ");
	scanf("%d", &date);
	printf("\nInserte el código locker de su pedido: ");
	scanf("%d", &code);

	int day, month, year, reminder; //split the date into day, month and year
	day=date/pow1(10, 6);
	reminder=date%pow1(10,6);
	month=reminder/pow1(10, 4);
	year=reminder % (pow1(10, 4));


	for (int i=0; i < lockercompartmentcount && bool==false; i++){
		int aux;
		if (lockercompartmentdata[i].lockercode == code){
			bool=true;
			int dayExpiry, monthExpiry, yearExpiry, reminderExpiry; //also the expiry date 
			dayExpiry=lockercompartmentdata[i].expirydate/pow1(10, 6);
			reminderExpiry=lockercompartmentdata[i].expirydate%pow1(10,6);
			monthExpiry=reminderExpiry/pow1(10, 4);
			yearExpiry=reminderExpiry % (pow1(10, 4));

			if (yearExpiry>=year && monthExpiry>=month && dayExpiry>=day){ //if the pickup is on time
				printf("\nSu pedido se encuentra en el compartimento %d.", lockercompartmentdata[i].compartmentid);
				changeCompartmentState(i);
				lockercompartmentdata[i].lockercode=0;
				lockercompartmentdata[i].placementdate=0;
				lockercompartmentdata[i].expirydate=0;
			}

			else {
				printf("\nHa excedido la fecha de recogida. Su pedido ha sido devuelto. Disculpe las molestias\n");
			}
		}
	}
}


void deleteLockerCompartment(char *locker, int numberCompartments){
	int aux=-1; //i cannot be negative
	for (int i=0; i < lockercompartmentcount && aux == -1; i++){
		if (strcmp(locker, lockercompartmentdata[i].lockerid)==0){
			aux=i;
		}
	}
	for (int i=aux; i < aux+numberCompartments;i++){
		rmLockerCompartment(aux);
	}
}

void newCompartment(char *locker, int numberCompartments){
	for (int i=0;i<numberCompartments;i++){
		addLockerCompartment(lockercompartmentdata[lockercompartmentcount-1]);
		strcpy(lockercompartmentdata[lockercompartmentcount-1].lockerid,locker);
		lockercompartmentdata[lockercompartmentcount-1].compartmentid=i+1;
		lockercompartmentdata[lockercompartmentcount-1].lockercode=0;
		strcpy(lockercompartmentdata[lockercompartmentcount-1].state, "vacío");
		lockercompartmentdata[lockercompartmentcount-1].placementdate=0;
		lockercompartmentdata[lockercompartmentcount-1].expirydate=0;
	}
}


void assignmentLocker(char *locker){
	int aux=0;
	for (int i=0;i<lockercompartmentcount && aux==0;i++){
		if (strcmp(locker, lockercompartmentdata[i].lockerid)==0 && strcmp(lockercompartmentdata[i].state,"vacío")==0){
			aux=1;
			changeLockerCode(i);
			changeCompartmentState(i);
		}
	}
}


void expirydateCompartment(char *locker, int compartment){
	for (int i=0;i<lockercompartmentcount;i++){
		if (strcmp(locker, lockercompartmentdata[i].lockerid) == 0 && lockercompartmentdata[i].compartmentid == compartment){
			int day, month, year, reminder;
			day=lockercompartmentdata[i].placementdate/pow1(10, 6);
			reminder=lockercompartmentdata[i].placementdate%pow1(10,6);
			month=reminder/pow1(10, 4);
			year=reminder % (pow1(10, 4));
			if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12){ //if the month has 31 days
				day=day+7;
				if (day>31){
					month++;
					day=day-31;
					if(month==13){//the only month that can modify the year is December
						year++;
						month=month-12;
					}
				}
			}
			if (month==4 || month==6 || month==9 || month==11){ //if the month has 30 days
				day=day+7;
				if (day>30){
					month++;
					day=day-30;
				}
			}
			if (month==2 && year%4==0){ //if the month is February and leap-year
				day=day+7;
				if (day>29){
					month++;
					day=day-29;
				}
			}
			if (month==2 && year%4==0){//if the month is February and not leap-year
				day=day+7;
				if (day>28){
					month++;
					day=day-28; 
				}
			}
			lockercompartmentdata[i].expirydate=day*pow1(10,6)+month*pow1(10,4)+year;
		}
	}
}